package modelo.persistenciaArquivo;

import java.io.IOException;
import java.util.ArrayList;
import modelo.dominio.Cliente;
import modelo.dominio.Motorista;
import modelo.dominio.Locacao;
import modelo.dominio.TipoLocacao;
import modelo.dominio.Veiculo;
import modelo.dominio.TipoVeiculo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.GregorianCalendar;

import java.text.SimpleDateFormat;

public class PersistenciaLocacao {
	
	// Lista de locações
	private static ArrayList<Locacao> listaLocacoes = new ArrayList<Locacao>();
	//private ArrayList<Locacao> locacoesEmAberto = new ArrayList<Locacao>();
	
	// Cadastro de locações
	public void cadastrarLocacao(Locacao locacao){
	    this.listaLocacoes.add(locacao);
	}
	
	// Obter a lista de locações
	public static ArrayList<Locacao> getListaLocacoes() {
		return listaLocacoes;
	}
	
	// Obter as locações em aberto
	public static ArrayList<Locacao> getLocacoesEmAberto() {
		ArrayList<Locacao> locacoesEmAberto = new ArrayList<Locacao>();
		for (Locacao locacao : listaLocacoes) {
			if(locacao.isFinalizada() == false){
				locacoesEmAberto.add(locacao);
			}
		}
		return locacoesEmAberto;
	}
	
	// Obter as locações finalizadas
	public static ArrayList<Locacao> getLocacoesFinalizadas() {
		ArrayList<Locacao> locacoesFinalizadas = new ArrayList<Locacao>();
		for (Locacao locacao : listaLocacoes) {
			if(locacao.isFinalizada() == true){
				locacoesFinalizadas.add(locacao);
			}
		}
		return locacoesFinalizadas;
	}
	
	// Consultar uma locação pelo id
	public Locacao consultaLocacao(Locacao locacao) {
		int i;
		for (i = 0; i < listaLocacoes.size(); i++) {
			if (listaLocacoes.get(i).getIdLocacao() == locacao.getIdLocacao()) {
				return listaLocacoes.get(i);
			}
		}
		return null; //Retorna Nulo caso não encontre
	}
	

	// Consultar uma locação pelo cpf do cliente
	public Locacao consultaLocacaoCliente(Locacao locacao) {
		int i;
		for (i = 0; i < listaLocacoes.size(); i++) {
			if (listaLocacoes.get(i).getCliente().getCpf() == locacao.getCliente().getCpf()) {
				return listaLocacoes.get(i);
			}
		}
		return null; //Retorna Nulo caso não encontre
	}
	
	// Consultar uma locação pela placa do veículo
	public Locacao consultaLocacaoVeiculo(Locacao locacao) {
		int i;
		for (i = 0; i < listaLocacoes.size(); i++) {
			if (listaLocacoes.get(i).getVeiculo().getPlaca().equals(locacao.getVeiculo().getPlaca())) {
				return listaLocacoes.get(i);
			}
		}
		return null; //Retorna Nulo caso não encontre
	}
	
	// Consultar uma locaçoes em Aberto
	public Locacao consultaLocacoesEmAberto(Locacao locacao) {
		int i;
		for (i = 0; i < listaLocacoes.size(); i++) {
			if (listaLocacoes.get(i).isFinalizada() == false) {
				return listaLocacoes.get(i);
			}
		}
		return null; //Retorna Nulo caso não encontre
	}
	
	// Consultar uma locaçoes Finalizadas
	public Locacao consultarLocacoesFinalizadas(Locacao locacao) {
		int i;
		for (i = 0; i < listaLocacoes.size(); i++) {
			if (listaLocacoes.get(i).isFinalizada() == true) {
				return listaLocacoes.get(i);
			}
		}
		return null; //Retorna Nulo caso não encontre
	}
	
	// Calcula o valor da locação
	public void calculaValorLocacao(Locacao locacao){
		double taxaBase, precoPorKm, precoDiaria, valor;
		double percentual = locacao.getVeiculo().getTipoVeiculo().getPercentual();
		long km;
		valor = 0;
		precoDiaria = locacao.getTipoLocacao().getPrecoDiaria();
		/* Cálculo do valor da locação por quilometragem */
		if (locacao.getTipoLocacao().getIdTipoLocacao() == 1){
			km = locacao.getQuilometragemEntrada() - locacao.getQuilometragemSaida();
			taxaBase = locacao.getTipoLocacao().getTaxaBase() * percentual;
			precoPorKm = locacao.getTipoLocacao().getPrecoPorKm() * percentual;
			valor = taxaBase + (precoPorKm * km);
		}
		/* Cálculo do valor da locação por diária */
		else if (locacao.getTipoLocacao().getIdTipoLocacao() == 2){
			valor = locacao.getPrevisaoDias() * precoDiaria * percentual;
		}
		locacao.setValorLocacao(valor);
	}
	
	// Calcula o valor total de uma lista de locações
	public double calculaValorLocacoes(ArrayList<Locacao> locacoes){
		double total = 0;
		for (int i = 0; i < locacoes.size(); i++) {
			total += locacoes.get(i).getValorLocacao();
		}
		return total;
	}
	
	// Calcula a receita esperada das locações em aberto
	public double calculaReceitaEsperada(ArrayList<Locacao> locacoes){
		double total = 0;
		PersistenciaVeiculo persistenciaVeiculo = new PersistenciaVeiculo();
		for (int i = 0; i < locacoes.size(); i++) {
			Veiculo veiculo = new Veiculo();
			retornaLocacao(locacoes.get(i));
			total += locacoes.get(i).getValorLocacao();
		}
		return total;
	}
	
	// Gravação da locação em arquivo
	public void salvarEmArquivo(ArrayList<Locacao> locacoes) throws IOException{
		int i;
		BufferedWriter writer = new BufferedWriter(new FileWriter("locacoes.txt"));
		PrintWriter output = new PrintWriter(writer);
		
		for (i = 0; i < locacoes.size(); i++) { 
			output.println (locacoes.get(i).getIdLocacao() + ";"
			+ locacoes.get(i).getQuilometragemSaida() + ";"
			+ locacoes.get(i).getQuilometragemEntrada() + ";"
			+ locacoes.get(i).getDataSaida().getTimeInMillis() + ";"
			+ locacoes.get(i).getDataDevolucao().getTimeInMillis() + ";"
			+ locacoes.get(i).getValorLocacao() + ";" 
			+ locacoes.get(i).getPrevisaoDias() + ";"
			+ locacoes.get(i).isFinalizada() + ";"
			+ locacoes.get(i).getTipoLocacao().getIdTipoLocacao() + ";"	//grava o id do TipoLocacao
			+ locacoes.get(i).getMotorista().getCnh() + ";"			//grava a placa do Veiculo
			+ locacoes.get(i).getCliente().getCpf()	+ ";"			//grava o CPF do Cliente
			+ locacoes.get(i).getVeiculo().getPlaca());
		}
		writer.close();
		output.close();
	}

	// Gravação da locação em arquivo
	public void acrecentarAoArquivo(Locacao locacoes) throws IOException{
		int i;
		BufferedWriter writer = new BufferedWriter(new FileWriter("locacoes.txt", true));
		PrintWriter output = new PrintWriter(writer);
		
		output.println (locacoes.getIdLocacao() + ";"
		+ locacoes.getQuilometragemSaida() + ";"
		+ locacoes.getQuilometragemEntrada() + ";"
		+ locacoes.getDataSaida().getTimeInMillis() + ";"
		+ locacoes.getDataDevolucao().getTimeInMillis() + ";"
		+ locacoes.getValorLocacao() + ";" 
		+ locacoes.getPrevisaoDias() + ";"
		+ locacoes.isFinalizada() + ";"
		+ locacoes.getTipoLocacao().getIdTipoLocacao() + ";"	//grava o id do TipoLocacao
		+ locacoes.getMotorista().getCnh() + ";"			//grava a placa do Veiculo
		+ locacoes.getCliente().getCpf()	+ ";"			//grava o CPF do Cliente
		+ locacoes.getVeiculo().getPlaca());
		writer.close();
		output.close();
	}
	
	// Leitura do arquivo
	public void lerArquivo(ArrayList<Locacao> locacoes) throws IOException{
		int idLocacao, previsaoDias;
		long quilometragemSaida, quilometragemEntrada, aux;
		Calendar dataSaida, dataDevolucao;
		double valorLocacao;
		boolean status;
		dataSaida = new GregorianCalendar();
		dataDevolucao = new GregorianCalendar();;
		File arquivo = new File("locacoes.txt");
		if(!arquivo.exists()){
			arquivo.createNewFile();
		}
		else {
			FileReader reader = new FileReader("locacoes.txt");
			BufferedReader leitor = new BufferedReader(reader);
				
			String linha = null;
			String [] vetor = null;

			while((linha = leitor.readLine()) != null) {
				vetor = linha.split(";");
				idLocacao = Integer.parseInt(vetor[0]);
				quilometragemSaida = Long.parseLong(vetor[1]);
				quilometragemEntrada = Long.parseLong(vetor[2]);
				aux = Long.parseLong(vetor[3]);
				dataSaida.setTimeInMillis(aux);
				aux = Long.parseLong(vetor[4]);
				dataDevolucao.setTimeInMillis(aux);
				valorLocacao = Double.parseDouble(vetor[5]);
				previsaoDias = Integer.parseInt(vetor[6]);
				status = Boolean.parseBoolean(vetor[7]);
				TipoLocacao tipoLocacao = new TipoLocacao(Integer.parseInt(vetor[8]));
				Motorista motorista = new Motorista(vetor[9]);
				Cliente cliente = new Cliente(vetor[10]);
				Veiculo veiculo = new Veiculo(vetor[11]);
				
				Locacao novaLocacao = new Locacao(idLocacao, quilometragemSaida,
					quilometragemEntrada, dataSaida, dataDevolucao, valorLocacao,
					previsaoDias, status, tipoLocacao, motorista, cliente, veiculo);		
				cadastrarLocacao(novaLocacao);
			}
			leitor.close();
			reader.close();
		}
	}
	
	// Converte uma string para um objeto GregorianCalendar
	public GregorianCalendar converteData(String data){
		GregorianCalendar dataRetorno = new GregorianCalendar();
		try {
			SimpleDateFormat formatoData = new SimpleDateFormat("dd/MM/yyyy");
			dataRetorno.getInstance();
			dataRetorno.setTime(formatoData.parse(data));
		} catch (Exception e) {}
		return dataRetorno;
	}
	
	// Cálculo da diferença em dias entre data de saída e a data de devolução
	public int calculaDiasDiferenca(Locacao locacao){
		long diferenca = locacao.getDataDevolucao().getTimeInMillis() -
		locacao.getDataSaida().getTimeInMillis();
		// Quantidade de milissegundos em um dia
		int tempoDia = 1000 * 60 * 60 * 24;
		int diasDiferenca = (int)diferenca / tempoDia;
		return diasDiferenca + 1;
	}
	
	// Retorna a locação com todos os seus atributos preenchidos
	public void retornaLocacao(Locacao locacao){
		int idTipoVeiculo, idTipoLocacao;
		
		PersistenciaCliente persistenciaCliente = new PersistenciaCliente();
		PersistenciaMotorista persistenciaMotorista = new PersistenciaMotorista();
		PersistenciaVeiculo persistenciaVeiculo = new PersistenciaVeiculo();
		PersistenciaTipoVeiculo persistenciaTipoVeiculo = new PersistenciaTipoVeiculo();
		PersistenciaTipoLocacao persistenciaTipoLocacao = new PersistenciaTipoLocacao();
		
		idTipoVeiculo = locacao.getVeiculo().getTipoVeiculo().getIdTipoVeiculo();
		idTipoLocacao = locacao.getTipoLocacao().getIdTipoLocacao();
		Cliente clientePesquisa = new Cliente(locacao.getCliente().getCpf());
		Motorista motoristaPesquisa = new Motorista(locacao.getMotorista().getCnh());
		Veiculo veiculoPesquisa = new Veiculo(locacao.getVeiculo().getPlaca());
		TipoVeiculo tipoVeiculoPesquisa = new TipoVeiculo(idTipoVeiculo);
		TipoLocacao tipoLocacaoPesquisa = new TipoLocacao(idTipoLocacao);
		
		Cliente cliente = new Cliente();
		Motorista motorista = new Motorista();
		Veiculo veiculo = new Veiculo();
		TipoVeiculo tipoVeiculo = new TipoVeiculo();
		TipoLocacao tipoLocacao = new TipoLocacao();
		
		cliente = persistenciaCliente.consultaClienteCpf(clientePesquisa);
		motorista = persistenciaMotorista.consultaMotorista(motoristaPesquisa);
		tipoVeiculo = persistenciaTipoVeiculo.buscaTipoVeiculoId(tipoVeiculoPesquisa);
		veiculo = persistenciaVeiculo.buscaVeiculoPorPlaca(veiculoPesquisa);
		veiculo.setTipoVeiculo(tipoVeiculo);
		tipoLocacao = persistenciaTipoLocacao.consultarTipoLocacao(tipoLocacaoPesquisa);
		locacao.setCliente(cliente);
		locacao.setMotorista(motorista);
		locacao.setVeiculo(veiculo);
		locacao.setTipoLocacao(tipoLocacao);
	}
	
}
